class Monitor {

    constructor(options) {
        let self = this;
		self.__debug = !! options.debug;
        self.child_process = require('child_process');
        self.GetMonitorData(1);
    }

    GetMonitorData(netTime) {
        let self = this;
        let pCPU = self._getCPUInfo();
        let pMem = self._getMemoryInfo();
        let pDisk = self._getDiskInfo();
        let pDataDisk = self._getDataDiskInfo();
        let pIO = self._getIOInfo();
        let pNet = self._getNetInfo(netTime);
        return Promise.all([pCPU, pMem, pDisk, pDataDisk,  pIO, pNet])
            .then(d => {
                let data = {
                    cpu: d[0],
                    mem: d[1],
                    disk: d[2],
                    disk_data: d[3],
                    io: d[4],
                };
                for(let attr in d[5]){
                    data['net_' + attr] = d[5][attr];
                }
				if (self.__debug){
					console.log('\n----------------------\n');
					console.log(data);
					console.log('\n----------------------\n');
				}
                return data;
            })
    }

    /**
     * 获取cpu使用率
     */
    _getCPUInfo() {
        let self = this;
        return new Promise( resolve => {
            self.child_process.exec( 'cat /proc/loadavg' , function(err, stdout , stderr ) {
                if(err || stderr) {
                    console.error('获取cpu使用率, error', err || stderr)
                    resolve({});
                    return;
                }
                let arr = stdout.split(' ').filter(d => d !== '');
                let r = Number(arr[0]) || 0;
                let info = Number((100 * r).toFixed(2));
                // console.log('cpu使用率', info)
                resolve({ratio: {value: info, unit: '%'}})
            });
        })

    }

    /**
     * 获取内存使用率
     */
    _getMemoryInfo() {
        let self = this;
        return new Promise( resolve => {
            self.child_process.exec( 'cat /proc/meminfo | head -n 5' , function(err, stdout , stderr ) {
                if(err || stderr) {
                    console.error('获取内存使用率, error', err || stderr)
                    resolve({});
                    return;
                }
                let data = {};
                let arr = stdout.split('\n');
                for( let item of arr ) {
                    if(! item )  continue;
                    let it = item.split(' ').filter(d => d !== '');
                    let attr = it[0].replace(':', '');
                    data[attr] = {value: Math.ceil(Number(it[1])/1024), unit: 'Mb'};
                }
                let MemTotal = !! data.MemTotal ? data.MemTotal.value : 0,
                    MemFree = !! data.MemFree ? data.MemFree.value : 0,
                    Buffers = !! data.Buffers ? data.Buffers.value : 0,
                    Cached = !! data.Cached ? data.Cached.value : 0;
                data.ratio = {value: Number((100*(MemTotal-MemFree-Buffers-Cached)/MemTotal).toFixed(2)), unit: '%'};
                // console.log('内存使用率', data)
                resolve(data);
            });
        })
    }

    /**
     * 获取磁盘使用率
     */
    _getDiskInfo() {
        let self = this;
        return new Promise( resolve => {
            self.child_process.exec( 'df -h /' , function(err, stdout , stderr ) {
                if(err || stderr) {
                    console.error('获取磁盘使用率, error', err || stderr)
                    resolve({});
                    return;
                }
                let data = stdout.split('\n')[1].split(' ').filter(d => d !== '');
                //容量  已用  可用 已用%

                let Size = data[1],
                    Used = data[2],
                    Avail = data[3],
                    UsageRatio = data[4];
                Size = {value: Number(Size.substring(0, Size.length-1)), unit: Size.substring(Size.length-1)};
                Used = {value: Number(Used.substring(0, Used.length-1)), unit: Used.substring(Used.length-1)};
                Avail = {value: Number(Avail.substring(0, Avail.length-1)), unit: Avail.substring(Avail.length-1)};
                UsageRatio = {value: Number(UsageRatio.substring(0, UsageRatio.length-1)), unit: UsageRatio.substring(UsageRatio.length-1)};
                // console.log('磁盘使用率', {Size, Used, Avail, UsageRatio});
                resolve({Size, Used, Avail, ratio: UsageRatio})
            });
        })

    }

    /**
     * 获取/data/目录所在磁盘使用率
     */
    _getDataDiskInfo() {
        let self = this;
        return new Promise( resolve => {
            self.child_process.exec( 'df -h /data/' , function(err, stdout , stderr ) {
                if(err || stderr) {
                    console.error('获取data磁盘使用率, error', err || stderr)
                    resolve({});
                    return;
                }
                let data = stdout.split('\n')[1].split(' ').filter(d => d !== '');
                //容量  已用  可用 已用%

                let Size = data[1],
                    Used = data[2],
                    Avail = data[3],
                    UsageRatio = data[4];
                Size = {value: Number(Size.substring(0, Size.length-1)), unit: Size.substring(Size.length-1)};
                Used = {value: Number(Used.substring(0, Used.length-1)), unit: Used.substring(Used.length-1)};
                Avail = {value: Number(Avail.substring(0, Avail.length-1)), unit: Avail.substring(Avail.length-1)};
                UsageRatio = {value: Number(UsageRatio.substring(0, UsageRatio.length-1)), unit: UsageRatio.substring(UsageRatio.length-1)};
                // console.log('data磁盘使用率', {Size, Used, Avail, UsageRatio});
                resolve({Size, Used, Avail, ratio: UsageRatio})
            });
        })

    }
    /**
     * 获取磁盘IO消耗
     */
    _getIOInfo() {
        let self = this;
        return new Promise( resolve => {
            self.child_process.exec( 'iostat -x -k -d' , function(err, stdout , stderr ) {
                if(err || stderr) {
                    console.error('获取磁盘IO消耗, error', err || stderr)
                    resolve({});
                    return;
                }
                let data = stdout.split('\n')[3].split(' ').filter(d => d !== '');
                //读kb/s  写kb/s  %util
                let rkB = {value: Number(data[5]), unit: 'kb'},
                    wkB = {value: Number(data[6]), unit: 'kb'},
                    ratio = {value: Number(data[13]), unit: '%'};
                // console.log('磁盘IO消耗', {rkB, wkB, ratio});
                resolve({rkB, wkB, ratio})
            });
        })

    }

    /**
     * 获取time(s)内网络数据传输平均值 byte/s
     */
    _getNetInfo(time) {
        let self = this;
        time = Number(time) || 10;
        return new Promise(resolve => {
            //rx 接收 tx 发送
            let data = {
                lo: {rx: {value: 0, unit: 'kbps'}, tx: {value: 0, unit: 'kbps'}},
                eth0: {rx: {value: 0, unit: 'kbps'}, tx: {value: 0, unit: 'kbps'}},
                eth1: {rx: {value: 0, unit: 'kbps'}, tx: {value: 0, unit: 'kbps'}}
            };
            let data1 = {};
            let data2 = {};
            self.child_process.exec( 'cat /proc/net/dev | tail -n +3' , function(err, stdout , stderr ) {
                if(err || stderr) {
                    console.error('获取网络传输速率, error', err || stderr)
                    resolve({});
                    return;
                }
                let arr = stdout.split('\n');
                for(let item of arr) {
                    if(! item) continue;
                    let arr2 = item.split(' ').filter(d => d !== '');
                    let attr = arr2[0].replace(':', '');
                    data1[attr] = {rx: arr2[1], tx: arr2[9]};
                }
            });
            setTimeout(() => {
                self.child_process.exec( 'cat /proc/net/dev | tail -n +3' , function(err, stdout , stderr ) {
                    if(err || stderr) {
                        console.error('获取网络传输速率, error', err || stderr)
                        resolve({});
                        return;
                    }
                    let arr = stdout.split('\n');
                    for(let item of arr) {
                        if(! item) continue;
                        let arr2 = item.split(' ').filter(d => d !== '');
                        let attr = arr2[0].replace(':', '');
                        data2[attr] = {rx: arr2[1], tx: arr2[9]};
                    }
                    for(let attr in data1){
                        let rx = parseInt((data2[attr].rx - data1[attr].rx) / time / 125);
                        let tx = parseInt((data2[attr].tx - data1[attr].tx) / time / 125);
                        if(!! data[attr]) {
                            data[attr].rx.value += rx;
                            data[attr].tx.value += tx;
                        }else {
                            data.eth1.rx.value += rx;
                            data.eth1.tx.value += tx;
                        }
                    }
                    // console.log('网络传输速率', data );
                    resolve(data)
                });
            }, time * 1000);
        })
    }

}

module.exports = Monitor;
